package epam.bookShelf.textReaders;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import epam.bookShelf.bookStuff.Book;
import epam.bookShelf.bookStuff.BookBuilder;
import epam.bookShelf.stuff.Library;

public class BookJSONReader {
    private static final String TITLE       = "title";
    private static final String AUTHOR      = "author";
    private static final String LOCATION    = "location";
    private static final String READED_DATE = "readedDate";
    private static final String DAT         = "dat";
    private static final String ISBN        = "isbn";
    private static final String DESCRIPTION = "description";
    
    Library lib;
    File file;
    
    public BookJSONReader(Library lib, File file) {
        this.lib = lib;
        this.file = file;
    }
    
    public void startParse() throws IllegalField, IllegalFieldValue {
        BufferedReader in;
        try {
            in = new BufferedReader(new FileReader(file));
            
            StringBuffer averallStr = new StringBuffer();
            String tempStr = in.readLine();
            
            while (tempStr != null) {
                averallStr.append(tempStr + "\n");
                tempStr = in.readLine();
            }            
            
            Pattern pat = Pattern.compile("^\\{([^+]*)\\}$");            
            Matcher match = pat.matcher(averallStr);
            match.find();                                  
            String str = match.group(1);
            
            pat = Pattern.compile("(\"(\\w+)\"\\s*:\\s*)?(\\{([^}]*)\\})");
            match = pat.matcher(str);
                       
            BookBuilder builder = new BookBuilder();
            
            String type;
            
            while (match.find()) {
                type = match.group(2);
                if (type.equals("book")) {
                    lib.addBook(parceBook(match, builder));
                }
            }
            
            in.close();
        } catch (FileNotFoundException e) {
            System.out.println("I/O problem");
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    private Book parceBook(Matcher match, BookBuilder builder) 
        throws IllegalFieldValue, IllegalField
    {
        String name, value, inner;            
        Matcher inMatch;
                        
        inner = match.group(4);
        
        inMatch = 
            Pattern.
            compile("(\"(\\w*)\")\\s*:\\s*(\"[^\"]*\"|\\d+|\\[.*\\])").
            matcher(inner);
        while (inMatch.find()) {
            name = inMatch.group(2);
            value = inMatch.group(3);
            
            if (name.equals(TITLE)) {
                builder.setTitle(value);
            } else if (name.equals(AUTHOR)) {
                builder.setAuthorName(value);
            } else if (name.equals(LOCATION)) {
                Scanner scan = new Scanner(value);
                try {
                    builder.setLocationId(scan.nextLong());
                } catch (InputMismatchException e) {
                    throw new IllegalFieldValue("Incorrect value of readed date");
                } 
            } else if (name.equals(READED_DATE)) {
                Scanner scan = new Scanner(value);
                try {
                    builder.setReadedDate(scan.nextInt());
                } catch (InputMismatchException e) {
                    throw new IllegalFieldValue("Incorrect value of readed date");
                }    
            } else if (name.equals(DAT)) {
                Scanner scan = new Scanner(value);
                try {
                    builder.setDat(scan.nextInt());
                } catch (InputMismatchException e) {
                    throw new IllegalFieldValue("Incorrect value of date");
                }
            } else if (name.equals(ISBN)) {
                Scanner scan = new Scanner(value);
                try {
                    builder.setIsbn(scan.nextInt());
                } catch (InputMismatchException e) {
                    throw new IllegalFieldValue("Incorrect value of isbn");
                }
            } else if (name.equals(DESCRIPTION)) {
                builder.setDescription(value);
            } else {
                throw new IllegalField(name + " - incorrect field");
            }
        }
        
        return builder.getBook();
    }
}
